package com.tensquare.encrypt.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.netflix.zuul.http.ServletInputStreamWrapper;
import com.tensquare.encrypt.rsa.RsaKeys;
import com.tensquare.encrypt.service.RsaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.nio.charset.Charset;

/**
 * 网关的过滤器
 */
@Component
public class RSARequestFilter extends ZuulFilter {

    @Autowired
    private RsaService rsaService;

    // 过滤器生效的位置，"pre"请求转发前
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * 过滤器执行的优先顺序，值越小越优先
     * @return
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 是否启用过滤器，返回true时，就会执行run方法
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        System.out.println("到这来了......");
        // 获取请求对象
        RequestContext rc = RequestContext.getCurrentContext();
        HttpServletRequest request = rc.getRequest();
        //- 获取请求中的输入流(二进制数据)
        try {
            ServletInputStream is = request.getInputStream();
            //- 把输入流转成字符串UTF-8(密文)
            if(null != is){
                // 转成字符串，得到的是密文
                String requestBody = StreamUtils.copyToString(is, Charset.forName("UTF-8"));
                System.out.println("密文::" + requestBody);
                //- 如果有值则使用密钥解密(json格式)
                String reqeustData = rsaService.rsaDecryptDataPEM(requestBody, RsaKeys.getServerPrvKeyPkcs8());
                //- 重构请求并把解密结果写入到zuul请体中
                byte[] bytes = reqeustData.getBytes();
                rc.setRequest(new HttpServletRequestWrapper(request){
                    // 原来的请求内容是密文字符串，修改请求内容为解密后的json格式数据
                    @Override
                    public int getContentLength() {
                        return bytes.length;
                    }

                    @Override
                    public long getContentLengthLong() {
                        return bytes.length;
                    }

                    @Override
                    public ServletInputStream getInputStream() throws IOException {
                        // 返回解密的内容 替换原来的请求体内容
                        return new ServletInputStreamWrapper(bytes);
                    }
                });
                //- 设置请求头类型application/json
                rc.addZuulRequestHeader("Content-Type","application/json;charset=utf-8");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
}
